package com.qf.realm;

import com.qf.mapper.PermissionMapper;
import com.qf.mapper.RoleMapper;
import com.qf.mapper.UserMapper;
import com.qf.pojo.SysUsers;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;

/**
 *  需要自定义的MyRealm对象 查询Mysql数据库中的数据
                 CachingRealm,
               AuthenticatingRealm, : 进行认证
              AuthorizingRealm,
            ModularRealmAuthenticator




  Shiro：
     第一大功能：认证  Authenticating
     第二大功能：授权  Authorizing


 AuthenticationInfo:  认证信息

 * @author lixu
 */
public class MyRealm extends AuthorizingRealm {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    /**
     *  授权
     * @param principals 认证方法返回对象中的用户信息（用户名）
     *   the primary identifying principals of the AuthorizationInfo that should be retrieved.
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //SysUsers sysUsers = (SysUsers) principals;
        SysUsers sysUsers = (SysUsers)principals.getPrimaryPrincipal();


        //1:当前用户添加角色  一个用户对应多个角色
        Set<String> roles = roleMapper.findRoleSetByUid(sysUsers.getId());//
        //2:当前用户添加权限 一个用户对应多个权限
        Set<String> stringPermissions = permissionMapper.findPermSetByUid(sysUsers.getId());




        //3:返回对象AuthorizationInfo授权信息：包含多个角色 多个权限
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roles);
        authorizationInfo.setStringPermissions(stringPermissions);
        return authorizationInfo;
    }

    /**
     *  认证方法
     * @param token the authentication token containing the user's principal and credentials.
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1:接收到用户名及密码
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = usernamePasswordToken.getUsername();
        String password = new String(usernamePasswordToken.getPassword());
        //2:连接Mysql数据库查询用户对象
        //根据用户名用户一个用户对象
        SysUsers sysUsers = userMapper.findUserByUserName(username);
        if(null == sysUsers){
            //此用户不存在
            throw new UnknownAccountException("此用户不存在");
        }
        //3:校验密码是否正确
        if(!sysUsers.getPassword().equals(password)){
            throw new IncorrectCredentialsException("密码不正确");
        }
        //4:判断当前帐户是否激活
        if(1 != sysUsers.getStatus()){
            throw new DisabledAccountException("帐户未激活 ");
        }
        //5:成功了 返回用户相关信息
        AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                sysUsers,password,this.getName());
        return authenticationInfo;
    }
}
